<template>
  <div>
<!--面包屑导航  -->
    <el-breadcrumb separator-class="el-icon-arrow-right">
      <el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item>用户管理</el-breadcrumb-item>
      <el-breadcrumb-item>用户列表</el-breadcrumb-item>
    </el-breadcrumb>

    <!--卡片区域-->
    <el-card >

      <el-row :gutter="20">
        <!--搜索框-->
        <el-col :span="8">
              <el-input placeholder="请输入内容" v-model="params.query"  clearable @clear="getUsers()">   <!-- clear clearable执行后自动调用clear方法-->
                <el-button  slot="append"  icon="el-icon-search" @click="getUsers()"></el-button>
                <!--在一个支持 "append" 插槽的父组件（很可能是输入框或其他类似组件）的尾部添加一个带有搜索图标的按钮。
                    "append" 插槽通常被设计为位于组件的尾部
                -->
              </el-input>
        </el-col>

<!--        添加用户按钮-->
        <el-col :span="4">
             <el-button type="primary" @click="userAdddialogVisible=true">添加用户</el-button>
        </el-col>
      </el-row>
<!--      数据表格-->

            <el-table :data="userList" border >  <!--将 userList 的值绑定到表格的 data 属性上。这意味着表格将使用 userList 中的数据来渲染行-->
              <el-table-column prop="username" label="姓名" ></el-table-column>
              <el-table-column prop="email" label="邮箱" ></el-table-column>
              <el-table-column prop="mobile" label="电话" ></el-table-column>
              <el-table-column prop="role_name" label="角色" ></el-table-column>
              <el-table-column  label="状态" >
<!--                根据状态的值来进行显示
                    msg_status:true   打开
                    msg_status:false  关闭

                    <el-switch
                      v-model="value1"
                      active-text="按月付费"
                      inactive-text="按年付费">
                    </el-switch>
-->
              <!-- 基于作用域插槽来实现 ,就是为了获取状态的值
                    需求：
                        在页面对状态进行改变的时候，需要发送请求到后端进行修改状态的操作
                        change	switch 状态发生变化时的回调函数	新状态的值
              -->
                    <template slot-scope="scope"> <!--scope代表当前这行数据本身-->
                      <el-switch v-model="scope.row.mg_state" @change="user_state_change(scope.row)"></el-switch>
                      <!-- scope.row 用于引用当前行数据的属性。其中 row 属性通常指向当前行的数据。-->
                    </template>
              </el-table-column>
                      <!--
                          基于作用域插槽来实现,为了在后面实现修改,删除,分配角色的时候获取
                          当前行的数据
                      -->
              <el-table-column  label="操作" >
                    <template slot-scope="scope">
                      <!--由于你没有使用 scope 来绑定任何数据或事件，所以 scope 在这里看起来是多余的。但保留 slot-scope="scope"
                          是为了表明这个插槽是一个作用域插槽，并允许你在需要的时候访问 scope 对象（包括 scope.row）-->
                      <!--编辑按钮-->
                      <el-button type="primary" icon="el-icon-edit" size="mini" @click="showEditDialog(scope.row.id)"></el-button>
                      <!--删除按钮-->
                      <el-button type="primary" icon="el-icon-delete"  size="mini" @click="removeUserById(scope.row.id)"></el-button>

                      <!--
                        需求:给分配角色的按钮加上文字提示,
                        effect:颜色
                        enterable:鼠标是否可进入到 tooltip 中   默认是true
                      -->

                          <el-tooltip  effect="dark" content="指定角色" placement="top-start" :enterable="false">
                               <el-button type="warning" icon="el-icon-setting"  size="mini"></el-button>
                          </el-tooltip>




                    </template>
              </el-table-column>

            </el-table>

                    <!--分页功能
                        :total   当前页面总共有多少条数据，该数据应该来自于后端
                        :pagesize 每页显示多少条数据
                        :current-page  当前页码
                    -->
                    <el-pagination
                        @size-change="handleSizeChange"
                        @current-change="handleCurrentChange"
                        :current-page="params.pagenum"
                        :page-sizes="[5, 10, 15, 20]"
                        :page-size="params.pagesize"
                        layout="total, sizes, prev, pager, next, jumper"
                        :total="total">
                    </el-pagination>

    </el-card>


    <!-- 添加用户的对话框   -->
            <el-dialog
                title="添加用户"
                :visible.sync="userAdddialogVisible"
                width="30%"
                @close="add_user_dialog">
               <!-- 内容-->
              <el-form :model="addForm" ref="addFormRef" :rules="addFormRules" label-width="70px">

                <el-form-item label="用户名" prop="username">
                  <el-input v-model="addForm.username"></el-input>
                </el-form-item>
                <el-form-item label="密码" prop="password">
                  <el-input v-model="addForm.password" type="password"></el-input>
                </el-form-item>
                <el-form-item label="邮箱" prop="email">
                  <el-input v-model="addForm.email"></el-input>
                </el-form-item>
                <el-form-item label="手机号" prop="mobile">
                  <el-input v-model="addForm.mobile"></el-input>
                </el-form-item>
              </el-form>
              <!--底部按钮区域-->
              <span slot="footer" class="dialog-footer">
            <el-button @click="userAdddialogVisible = false">取 消</el-button>
            <el-button type="primary" @click="add_user">确 定</el-button>
          </span>
            </el-dialog>


              <!-- 修改用户的对话框   -->
              <el-dialog
                  title="修改用户"
                  :visible.sync="editDialogVisible"
                  width="30%"
                  @close="editDialogClosed">
                <!-- 内容-->
                <el-form :model="editForm" ref="editFormRef" :rules="editFormRules" label-width="70px">

<!--                  需要回显的信息-->
                  <el-form-item label="用户名" prop="username">
                    <el-input v-model="editForm.username" disabled></el-input>
                  </el-form-item>

                  <el-form-item label="邮箱" prop="email">
                    <el-input v-model="editForm.email"></el-input>
                  </el-form-item>
                  <el-form-item label="手机号" prop="mobile">
                    <el-input v-model="editForm.mobile"></el-input>
                  </el-form-item>
                </el-form>
                <!--底部按钮区域-->
                <span slot="footer" class="dialog-footer">
                      <el-button @click="editDialogVisible = false">取 消</el-button>
                      <el-button type="primary" @click="editUserInfo">确 定</el-button>
                    </span>
              </el-dialog>


  </div>


</template>

<script>
export default {
  data() {
            const checkEmail = (rule, value, callback) => {
              // 验证邮箱的正则表达式
              const regEmail = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-])+/;
              if (regEmail.test(value)) {
                return callback();
              }
              callback("邮箱输入格式不匹配");
            };

    const checkMoblie = (rule, value, callback) => {
      //验证手机号的正则表达式
      const regMobile = /^(86|17951)?(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$/
      if (regMobile.test(value)) {
        return callback();
      }
      callback("手机号输入格式不匹配");
    };


    return {
      //后端需要的参数
      params: {
        //查询条件
        query: '',
        //当前页码
        pagenum: '1',
        //每页显示多少条数据
        pagesize: '20',

      },
      userList: [],
      total: 0,
      //添加用户对话框显示与关闭    false  不显示，  true 显示
      userAdddialogVisible: false,
      addForm: {
        username: '',
        password: '',
        email: '',
        mobile: '',

      },
      //表单校验规则
      addFormRules: {
        username: [
          {required: true, message: '请输入用户名', trigger: 'blur'},
          {min: 6, max: 16, message: '用户名的长度为6~16个字符', trigger: 'blur'}
        ],
        password: [
          {required: true, message: '请输入密码', trigger: 'blur'},
          {min: 6, max: 16, message: '密码的长度为6~16个字符', trigger: 'blur'}
        ],
        email: [
          {required: true, message: '请输入邮箱', trigger: 'blur'},
          //需要满足邮箱的格式
          {validator: checkEmail, trigger: 'blur'}
        ],
        mobile: [
          {required: true, message: '请输入手机号', trigger: 'blur'},
          //需要满足手机号的格式
          {validator: checkMoblie, trigger: 'blur'}
        ],
      },

      //控制修改用户的对话框
      editDialogVisible: false,
      editForm: {},
      editFormRules: {
        email: [
          {required: true, message: '请输入邮箱', trigger: 'blur'},
          //需要满足邮箱的格式
          {validator: checkEmail, trigger: 'blur'}
        ],
        mobile: [
          {required: true, message: '请输入手机号', trigger: 'blur'},
          //需要满足手机号的格式
          {validator: checkMoblie, trigger: 'blur'}
        ],
      },





    };
  },
  created() {
    /*
        调用后端接口获取用户数据进行显示
    */
    this.getUsers();

  },
  methods: {
    //获取后端用户数据
    async getUsers() {
      const {data: resp} = await this.$http.get('users', {params: this.params});   /*传递了一个 params 属性，它的值是 this.params*/
      /* {data} 获取的是原来对象里的data属性的值
      * data 是从 this.$http.get('users', {params: this.params}) 返回的对象中解构出来的属性，并且这个属性的值被赋值给了新的常量 data。
      *
      * {data: resp}:
          这是对象解构的完整形式，它允许你为从源对象中解构出来的属性指定一个不同的变量名。
      * */
      console.log(resp);
      if (resp.meta.status != 200) return this.$message.error("获取用户列表失败");

      //加载用户数据
      this.userList = resp.data.users;
      this.total = resp.data.total;

    },
    //handleSizeChange  每页显示多少条数据下拉菜单改变时会触发实践
    handleSizeChange(c_size) {
      // console.log(c_size);
      this.params.pagesize = c_size;
      //参数改变后，重新从后台加载数据
      this.getUsers();
    },
    /*handleCurrentChange 当前页发生改变后，
    *
    * */
    handleCurrentChange(c_size) {
      this.params.pagenum = c_size;

      this.getUsers();
    },
    /*
    * row  当前这一条数据
    * */
    async user_state_change(row) {
      console.log(row);
      //发送修改操作请求
      const {data: resp} = await this.$http.put(`users/${row.id}/state/${row.mg_state}`);
      console.log("resp");
      console.log(resp);
      if (resp.meta.status != 200) {
        return this.$message.error("用户状态更新失败");
        //取反，本来是false，修改为true失败了，要改回false，最后以后端是否修改成功为准
        row.mg_state = !row.mg_state;
      }
      this.$message.success("用户状态更新成功");
    },
    /*
    *   关闭添加用户dialog的时候触发
    * */
    add_user_dialog() {
      //清空表单的输入项
      this.$refs.addFormRef.resetFields();
    },
    /*
    *   保存用户信息
    *       1.校验前面的验证规则是否都通过
    *       2.
    * */
    add_user() {

      this.$refs.addFormRef.validate(async valid => {
        // console.log(valid);
        if (!valid) return
        //请求服务端
        const {data: resp} = await this.$http.post('users', this.addForm);
        // console.log(resp);
        if (resp.data.status != 201) {
          return this.$message.error("用户添加失败");
        }
        this.$message.success("用户添加成功");
        this.userAdddialogVisible = false;
        //添加成功后需要显示最新的数据
        this.getUsers();

      });
    },
    async showEditDialog(id) {
      const {data: res} = await this.$http.get("users/" + id);
      if (res.meta.status !== 200) {
        return this.$message.error("查询用户失败");
      }
      // console.log(res.data);
      //显示对话框
      this.editDialogVisible = true;
      //将查询出来的数据赋值给editForm进行回显
      this.editForm = res.data;

    },

    //关闭对话框的时候重置表单的输入
    editDialogClosed() {
      this.$refs.editFormRef.resetFields();
    },

    editUserInfo() {
      this.$refs.editFormRef.validate(async valid => {
        //校验输入的数据是否符合规范
        if (!valid) return;

        /*
        *   第二个参数表示需要修改的属性   是一个JSON格式
        *     email
        *     mobile
        * */
        const {data: res} = await this.$http.put('users/' + this.editForm.id,
            {
              email: this.editForm.email,
              mobile: this.editForm.mobile,
            });
        /*
            对修改后的结果进行判断
        */

        console.log(res);

        if (res.meta.status !== 200) {
          return this.$message.error("更新用户失败");
        }

        //关闭对话框
        this.editDialogVisible = false;
        //刷新数据
        this.getUsers();
        //提示修改成功
        this.$message.success("更新用户成功");
      });
    },

    async removeUserById(id) {
      //弹框询问用户是否删除数据
      const confirmResult = await this.$confirm(
          '此操作将永久删除该文件, 是否继续?',
          '提示',
          {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning',
          }
      ).catch(err=>err);
      //使用了 .catch(err=>err) 来捕获任何可能的错误或拒绝的情况，但实际上它并没有做太多事情，只是简单地将捕获到的值重新抛出。

      console.log(confirmResult);
      if (confirmResult !== 'confirm') {
        return this.$message.info('已取消删除');
      }
      const {data: res} = await this.$http.delete('users/' + id);   //数据传输到后端已经操作好啦  后面的逻辑都是为了反馈给用户信息
      if (res.meta.status !== 200) {
        return this.$message.error("删除用户失败");
      }
      this.$message.success("删除用户成功");
      this.getUsers();
    },




  },



}

</script>

<style>
.el-card{
  margin-top: 18px;
  font-size: 15px;
}

.el-table {
  margin-top: 18px;
  font-size: 15px;

}

.el-pagination {
  margin-top: 10px;
  font-size: 15px;
}


</style>

